////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file   CollabRCBotUnitTests\TestRhsTreeNode.h
///
/// @brief  Defines the test suite for CollabRC::Bot::AI::RhsTreeNode
////////////////////////////////////////////////////////////////////////////////////////////////////

#include <cxxtest/TestSuite.h>
#include "../CollabRCBot/RhsTreeNode.h"
#include "MockConstantTreeNode.h"
#include "MockOperationTreeNode.h"

class TestRhsTreeNode : public CxxTest::TestSuite
{
private:
    MockConstantTreeNode m_lhs, m_rhs;
public:
    inline TestRhsTreeNode():m_lhs(4),m_rhs(8) { };

    /** Tests the PerformOperation() function */
    void TestPerformOperation()
    {
        CollabRC::Bot::AI::RhsTreeNode node(m_lhs, m_rhs);
        TS_ASSERT_EQUALS(node.PerformOperation(4.0f, 8.0f), 8.0f);
    }

    /** Tests the Clone() operation */
    void TestClone()
    {
        CollabRC::Bot::AI::RhsTreeNode node(m_lhs, m_rhs);
        // Clones should optimize out the RHS if possible
        MockConstantTreeNode* clone = dynamic_cast<MockConstantTreeNode*>(node.Clone());
        bool oldATOF = CxxTest::abortTestOnFail();
        CxxTest::setAbortTestOnFail(true);
        TS_ASSERT(clone != NULL);
        CxxTest::setAbortTestOnFail(oldATOF);

        TS_ASSERT_EQUALS(clone->Compute(), node.Compute());
        TS_ASSERT_THROWS_NOTHING(delete clone);

        // Sometimes, however, it's not possible
        MockOperationTreeNode op(m_lhs, m_rhs);
        CollabRC::Bot::AI::RhsTreeNode node2(op);
        CollabRC::Bot::AI::RhsTreeNode* clone2 = dynamic_cast<CollabRC::Bot::AI::RhsTreeNode*>(node2.Clone());
        CxxTest::setAbortTestOnFail(true);
        TS_ASSERT(clone2 != NULL);
        CxxTest::setAbortTestOnFail(oldATOF);

        TS_ASSERT_EQUALS(clone2->Compute(), m_rhs.Compute());
        TS_ASSERT_THROWS_NOTHING(delete clone2);
    }
};
